package main

import (
	"database/sql"
	"elegantGo/chapter07/pkg/validate"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/go-playground/validator/v10"
	_ "github.com/go-sql-driver/mysql"
	"net/http"
	"regexp"
)

type Article struct {
	ID      int
	Title   string
	Content string

	IDParam string
	SQL     string
	ErrMsg  string
}

func sqlInject(s string) bool {
	detectSqlInjectRegex := `(?:')|(?:--)|(/\\*(?:.|[\\n\\r])*?\\*/)|(\b(select|update|and|or|delete|insert|trancate|char|chr|into|substr|ascii|declare|exec|count|master|into|drop|execute)\b)`
	return regexp.MustCompile(detectSqlInjectRegex).MatchString(s)
}

func main() {

	validate.RegisterValidation("sqlinject", func(fl validator.FieldLevel) bool {
		return !sqlInject(fl.Field().String())
	})
	
	dsn := "root:123456@tcp(127.0.0.1:3306)/bbs?charset=utf8mb4&parseTime=true&loc=Local"
	db, err := sql.Open("mysql", dsn)
	if err != nil {
		panic(err)
	}

	srv := gin.Default()
	srv.GET("/article", func(c *gin.Context) {
		id := c.DefaultQuery("ID", "")

		query := fmt.Sprintf("select id, title, content from articles where id=%s", id)
		row := db.QueryRowContext(c.Request.Context(), query)

		//query := "select id, title, content from articles where id=?"
		//row := repo.db.QueryRowContext(ctx, query, id)

		var article Article
		article.IDParam = id
		article.SQL = query
		if row.Err() != nil {
			article.ErrMsg = row.Err().Error()
		}
		row.Scan(&article.ID, &article.Title, &article.Content)

		c.JSON(http.StatusOK, article)
	})

	srv.Run(":80")
}
